package com.hzjq.rxblast.ui

import android.content.Context
import android.content.Intent
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import com.hzjq.core.Blast
import com.hzjq.core.BlastDelegate
import com.hzjq.core.bean.*
import com.hzjq.core.callback.Callback
import com.hzjq.core.callback.MainRunnable
import com.hzjq.core.callback.ProgressCallback
import com.hzjq.core.callback.ThreadRunnable
import com.hzjq.core.event.PioUnEnableEvent
import com.hzjq.rxblast.R
import com.hzjq.rxblast.adapter.RegisterAdapter
import com.hzjq.rxblast.callback.ChargeCallback
import com.hzjq.rxblast.callback.OnChargeClickListener
import com.hzjq.rxblast.event.LogEvent
import com.lxj.xpopup.XPopup
import com.lxj.xpopup.core.BasePopupView
import com.lxj.xpopup.interfaces.SimpleCallback
import com.wxl.common.AppContext
import com.wxl.common.base.AbsActivity
import com.wxl.common.util.Toll
import io.reactivex.Observable
import io.reactivex.ObservableEmitter
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_register_cap_layout.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode

class RegisterCapActivity : AbsActivity() {

    companion object {
        private var chargeClick: OnChargeClickListener? = null
        fun start(
            context: Context,
            caps: ArrayList<CapEntity>,
            chargeClick: OnChargeClickListener
        ) {
            if (caps.size > BlastDelegate.getDelegate().getMaxSupportCapCount()) {
                Toll.toll("雷管超过最大组网负载数")
                return
            }
            BlastDelegate.getDelegate().setMaxSupportCapCount(caps.size)
            RegisterCapActivity.chargeClick = chargeClick
            val intent = Intent(context, RegisterCapActivity::class.java)
            intent.putExtra("caps", caps)
            context.startActivity(intent)
        }
    }

    private val caps = arrayListOf<CapEntity>()
    private val registerResultCaps = arrayListOf<ErrorCapEntity>()
    private val mRegisterAdapter = RegisterAdapter(arrayListOf())
    private var disposable: Disposable? = null
    private var maxDelay = 0L
    private var warnPopupView : BasePopupView? = null

    override fun getCreateContentViewId(): Int {
        return R.layout.activity_register_cap_layout
    }

    override fun onCreateViewChanged() {
        AppContext.appContext.init(application, true)
        registerCapOkCount.text = "正确:-"
        registerCapErrorCount.text = "错误:-"
        registerCapListView.layoutManager = LinearLayoutManager(this)
        registerCapListView.adapter = mRegisterAdapter
        caps.clear()
        caps.addAll(intent.getSerializableExtra("caps") as ArrayList<CapEntity>)

        findMaxDelay()

        registerRetryBtn.isEnabled = false
        registerRetryBtn.isClickable = false
        registerRetryBtn.setOnClickListener {
            registerRetryBtn.isEnabled = false
            registerRetryBtn.isClickable = false
            onRetryClick()
        }

        registerChargeBtn.isEnabled = false
        registerChargeBtn.isClickable = false
        registerChargeBtn.setOnClickListener {
            registerChargeBtn.isEnabled = false
            registerChargeBtn.isClickable = false
            onChargeClick()
        }
        registerRetryCancel.setOnClickListener {
            registerRetryCancel.isEnabled = false
            onShowBack()
        }
    }


    private fun findMaxDelay() {
        BlastDelegate.getDelegate()
            .post(object : ThreadRunnable<Long> {
                override fun run(e: ObservableEmitter<Long>) {
                    caps.forEach {
                        if (maxDelay < it.delay) {
                            maxDelay = it.delay
                        }
                    }
                    e.onNext(maxDelay)
                }
            }, object : MainRunnable<Long> {
                override fun run(t: Long) {
                    onRegisterCap()
                }
            })
    }


    private fun onRegisterCap() {
        registerChargeBtn.isEnabled = false
        registerChargeBtn.isClickable = false
        registerRetryBtn.isEnabled = false
        registerRetryBtn.isClickable = false
        EventBus.getDefault().post(LogEvent("开始组网"))
        registerResultCaps.clear()
        mRegisterAdapter.notifyDataSetChanged()
        registerCapOkCount.text = "正确:-"
        registerCapErrorCount.text = "错误:-"
        Blast.getInstance().quickRegister()
            .onQuickRegister(caps, maxDelay, object : ProgressCallback<CapProgressEntity> {
                override fun onError(errorCode: ErrorResult) {
                    registerRetryBtn.isEnabled = true
                    registerRetryBtn.isClickable = true
                    registerCapProgressAction.text = errorCode.errorAction
                }

                override fun onProgressChanged(progress: Int, total: Int, action: String) {
                    BlastDelegate.getDelegate().post(
                        Runnable {
                            registerCapProgressBar.max = total
                            registerCapProgressBar.progress = progress
                            registerCapProgressAction.text = "${action}..."
                        }
                    )
                }

                override fun onResult(t: CapProgressEntity) {
                    if (t.isEnd) {
                        EventBus.getDefault().post(LogEvent("组网成功"))
                        registerCapOkCount.text = "正确:${caps.size}"
                        registerCapErrorCount.text = "错误:0"
                        convertOkCap()
                    }
                    registerCapDy.text = t.mVoltage.toString() + "V"
                    registerCapDl.text = t.mElectric.toString() + "mA"
                }

                override fun onRetryCountChanged(retryCount: Int, action: String) {
                    registerCapProgressAction.text = "${action}($retryCount)..."
                }

            }, Consumer<ErrorReadCapEntity> {
                if (it.caps[it.caps.size - 1].isScanEnd) {
                    EventBus.getDefault().post(LogEvent("组网失败"))
                    convertErrorCap(it)
                }

            })
    }


    private fun onRetryClick() {
        registerCapProgressLayout.visibility = View.VISIBLE
        registerCapListView.visibility = View.GONE
        onRegisterCap()
    }


    private fun onChargeClick() {
        val goOn = chargeClick!!.onChargeClick(this, object : ChargeCallback {
            override fun go() {
                registerChargeBtn.isEnabled = true
                registerChargeBtn.isClickable = true
            }
        })

        if (goOn) {
            Blast.getInstance().quickRegister().cancel()
            ChargeActivity.start(this@RegisterCapActivity, registerResultCaps, maxDelay)
            finish()
        }
    }


    private fun showCaps() {
        registerCapProgressLayout.visibility = View.GONE
        registerCapListView.visibility = View.VISIBLE
        mRegisterAdapter.setNewInstance(registerResultCaps)
        registerRetryBtn.isEnabled = true
        registerRetryBtn.isClickable = true
    }


    private fun convertOkCap() {
        registerChargeBtn.isEnabled = true
        registerChargeBtn.isClickable = true
        registerCapProgressAction.text = "正在组装雷管信息..."
        disposable?.dispose()
        disposable = Observable.create<MutableList<ErrorCapEntity>>() {
            registerResultCaps.clear()
            caps.forEach {
                val ecp = ErrorCapEntity()
                ecp.errorCode = 0
                ecp.cap = it
                registerResultCaps.add(ecp)
            }
            it.onNext(registerResultCaps)
        }.subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                showCaps()
            }
    }


    private fun convertErrorCap(result: ErrorReadCapEntity) {
        disposable?.dispose()
        disposable = Observable.create<MutableList<ErrorCapEntity>>() {
           val temp = arrayListOf<String>()
            registerResultCaps.clear()
            result.errors.forEach {
                if(!temp.contains(it.cap!!.uid)){
                    temp.add(it.cap!!.uid)
                    registerResultCaps.add(it)
                }
            }
            temp.clear()
            it.onNext(registerResultCaps)
        }.subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe {
                registerCapOkCount.text = "正确:0"
                registerCapErrorCount.text = "错误:${it.size}"
                showCaps()
            }
    }


    override fun getPageTitle(): String {
        return "起爆网络检测"
    }

    override fun onDestroy() {
        super.onDestroy()
        disposable?.dispose()
    }

    override fun onBackPressed() {
        onShowBack()
    }

    override fun onBackClick(): Boolean {
        onShowBack()
        return false
    }


    private fun onShowBack() {
        if (warnPopupView != null && warnPopupView!!.isShow) {
            return
        }


        warnPopupView=   XPopup.Builder(this)
            .setPopupCallback(object : SimpleCallback() {
                override fun onDismiss() {
                    registerRetryCancel.isEnabled = true
                }
            })
            .hasShadowBg(false)
            .asConfirm("提示", "是否终止当前操作？", {
                exitRegister()
            }, {
                registerRetryCancel.isEnabled = true
            }).show()
    }


    private fun exitRegister() {
        val show = XPopup.Builder(this)
            .hasShadowBg(false)
            .asLoading("正在退出,请等待...")
            .show()

        Blast.getInstance().quickRegister()
            .exitQuickRegister(object : Callback<Boolean> {
                override fun onError(errorCode: ErrorResult) {
                    show.dismiss()
                    Toll.toll("退出失败")
                }

                override fun onResult(t: Boolean) {
                    show.dismiss()
                    if (t) {
                        finish()
                    } else {
                        Toll.toll("退出失败")
                    }
                }

                override fun onRetryCountChanged(retryCount: Int, action: String) {

                }
            })

    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onPioUnEnableEvent(e: PioUnEnableEvent) {
        showPioUnEnablePop(this)
    }
}